﻿package com.sz.courseserial.dao.impl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.sz.common.ICommonDAO;
import com.sz.common.SZUtility;
import com.sz.courseserial.dao.ICourseSerialDAO;
import com.sz.common.ConstDefine;

public class CourseSerialDAO extends SqlMapClientDaoSupport implements ICourseSerialDAO{
	
	protected final Log logger = LogFactory.getLog(getClass());
	
	private ICommonDAO commonDAO = null;

	public ICommonDAO getCommonDAO() {
		return commonDAO;
	}

	public void setCommonDAO(ICommonDAO commonDAO) {
		this.commonDAO = commonDAO;
	}

	@SuppressWarnings("unchecked")
	public long addCourseSerial(Map map) throws Exception {
		Object obj = getSqlMapClient().insert("courseserial_sqlmap.insert_CourseSerial", map);
		return obj==null ? 0 : Long.parseLong(obj.toString());
	}
	
	@SuppressWarnings("unchecked")
	public List queryCourseSerial(Map map) throws Exception {		
		List list = getSqlMapClient().queryForList("courseserial_sqlmap.query_CourseSerial", map);
		return addition(list);
	}
	
	@SuppressWarnings("unchecked")
	public long queryCourseSerialCount(Map map) throws Exception {
		Map r = (Map)getSqlMapClient().queryForObject("courseserial_sqlmap.query_CourseSerialCount", map);
		return Long.parseLong(r.get("COUNT").toString());
	}
	
	@SuppressWarnings("unchecked")
	public List queryCourseSerial2(Map map) throws Exception {		
		List list = getSqlMapClient().queryForList("courseserial_sqlmap.query_CourseSerial2", map);
		return addition(list);
	}
	
	@SuppressWarnings("unchecked")
	public long queryCourseSerialCount2(Map map) throws Exception {
		Map r = (Map)getSqlMapClient().queryForObject("courseserial_sqlmap.query_CourseSerialCount2", map);
		return Long.parseLong(r.get("COUNT").toString());
	}
	
	@SuppressWarnings("unchecked")
	public List queryCourseSerialPage(Map map) throws Exception {
		List list = getSqlMapClient().queryForList("courseserial_sqlmap.query_CourseSerialPage", map);
		return addition(list);
	}
	
	@SuppressWarnings("unchecked")
	public List queryCourseSerialPage2(Map map) throws Exception {
		List list = getSqlMapClient().queryForList("courseserial_sqlmap.query_CourseSerialPage2", map);
		return addition(list);
	}
	
	@SuppressWarnings("unchecked")
	public List queryTicketStatusList() throws Exception {
		return getSqlMapClient().queryForList("ticket_sqlmap.query_TicketStatusList");
	}
	
	/**
	 * TICKET_ID
	 * LOCK_MANAGER 对于解锁指当前订单的锁定者(做校验用)
	 * MYVERSION 订单的VERSION(做校验用)
	 * LOCKFLAG： 0解锁/1锁定
	 */
	@SuppressWarnings("unchecked")
	public String lockTicket(Map map) throws Exception {
		/**锁定
		 * 1. 可以查询到订单
		 * 2. lock_manager字段为空(未被锁定)
		 * 3. version未变
		 * 4. 订单状态不能为：
			 	81	客户取消完成
			 	82 	商家取消完成
			 	83	订单确认失败，已取消
		 */
		
		/**解锁
		 * 1. 可以查询到订单
		 * 2. lock_manager字段不为空(被锁定),且与传入的LOCK_MANAGER相同
		 * 3. version未变
		 * 
		 */
		
		String ticket_id = map.get("TICKET_ID").toString();
		String lock_manager = map.get("LOCK_MANAGER").toString();
		String myversion = map.get("MYVERSION").toString();
		String lockFlag = map.get("LOCKFLAG").toString(); // 1 锁定， 0 解锁
		
		String sql = String.format("select cust_tel, status, lock_manager, version from ticket where ticket_id = %s", ticket_id);
		Map r = (Map)commonDAO.queryForObject(sql);		
		if(r == null) return "查询不到订单";	
		
		String cust_tel = r.get("CUST_TEL").toString(); //作为订单的文本标识
		
		if(lockFlag.equals("1")) { //锁定
			
			if(r.get("LOCK_MANAGER") != null) return cust_tel+"订单已被锁定";
			
			String ts = r.get("VERSION").toString();
			if(!myversion.equals(ts)) return cust_tel+"订单发生了更改";
			
			long status = Long.valueOf(r.get("STATUS").toString());
			if(81 == status || 82 == status || 83 == status) {
				return cust_tel+"订单已被取消";
			} else if(99 == status) {
				return cust_tel+"订单已经确认完成，不能被锁定";
			} else {
				Map param = new HashMap();
				param.put("LOCK_MANAGER", lock_manager);
				param.put("TICKET_ID", ticket_id);
				getSqlMapClient().update("ticket_sqlmap.update_LockManager", param);
				return null;
			}
		} else if(lockFlag.equals("0")){ //解锁
			
			if(r.get("LOCK_MANAGER") == null) return cust_tel+"订单未被锁定";
			if(lock_manager.equals(r.get("LOCK_MANAGER").toString()) == false) return cust_tel+"订单的锁定者已改变";
			
			String ts = r.get("VERSION").toString();
			if(!myversion.equals(ts)) return cust_tel+"订单发生了更改";
			
			//更新
			getSqlMapClient().update("ticket_sqlmap.update_LockManagerToNULL", ticket_id);
			return null;
		} else {
			return "未知的操作类型";
		}
	}
	
	/**
	 * 取消订单
	 * @param map
	 * 	TICKET_ID
	 * 	MYVERSION
	 * 	OPERATOR
	 * 	CANCEL_FROM : 1客户/2商家
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public String cancelTicket(Map map) throws Exception {
		/**
		 * 1. 可以查询到订单
		 * 2. 订单状态不能为：
				31	客户取消,待通知商家	
				41	商家取消,待通知客户
			 	81	客户取消完成
			 	82 	商家取消完成
			 	51	商家确认失败，待通知客户
			 	52	客户确认失败，待通知商家
			 	83	订单确认失败，已取消
		 * 3. version未变
		 */
		
		/***注意：与editTicket、nextStatus 的逻辑很相似，以后如果更改，要考虑editTicket和nextStatus是否也要改 **/
		/******** 例如何时清空锁定者     **/
		
		String ticket_id = map.get("TICKET_ID").toString();
		String myversion = map.get("MYVERSION").toString();		
		String operator = map.get("OPERATOR").toString();
		String from = map.get("CANCEL_FROM").toString(); //发起者 1客户 2商家
		
		String sql = String.format("select cust_tel, status, lock_manager, version from ticket where ticket_id = %s", ticket_id);
		Map r = (Map)commonDAO.queryForObject(sql);		
		if(r == null) return "查询不到订单";	
		
		String cust_tel = r.get("CUST_TEL").toString(); //作为订单的文本标识
		
		long cur_status = Long.valueOf(r.get("STATUS").toString()); //订单当前状态
		if(31 == cur_status || 81 == cur_status) {
			return cust_tel + "订单已被客户取消";
		} else if(41 == cur_status || 82 == cur_status) {
			return cust_tel + "订单已被商家取消";
		} else if(51 == cur_status || 52 == cur_status || 83 == cur_status) {
			return cust_tel + "订单由于确认失败，已经被取消";
		} else {
			//do nothing
		}		
		
		String ts = r.get("VERSION").toString();
		if(!myversion.equals(ts)) return cust_tel+"订单发生了更改";
		
		String new_status;		
		if(from.equals(ConstDefine.s_fromCustom)) { //客户取消
			if(cur_status == 1 && r.get("LOCK_MANAGER")==null) {
				//客户发起的取消并且订单当前的状态为“客户下单,待商家确认”(即客户刚起了单还没联系商家，又退单)
				//则不用通知商家
				//之所以判断LOCK_MANAGER为null是担心其实中台已经与商家联系了，但是未及时提交
				new_status = "81";
			} else {
				new_status = "31";
			}
		} else if(from.equals(ConstDefine.s_fromBusiness)) { //商家取消
			new_status = "41";
		} else {
			return "未知的取消操作发起方";
		}
		
		Map param = new HashMap();
		param.put("TICKET_ID", ticket_id);
		param.put("STATUS", new_status);
		param.put("OPERATOR", operator);
		param.put("__SET_LOCKMANAGER_NULL", map.get("__SET_LOCKMANAGER_NULL")); //若前台传了__SET_LOCKMANAGER_NULL的值， 则清空锁定者
		
		getSqlMapClient().update("ticket_sqlmap.update_Status", param);
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public String editCourseSerial(Map map) throws Exception {

		String serial_id = map.get("SERIAL_ID").toString();
		String name = map.get("NAME").toString();		
		String desc = map.get("DESCRIP").toString();
		
		String sql = String.format("select serial_id,name,descrip,display_order,parent_id,serial_level from course_serial where serial_id = %s", serial_id);
		Map r = (Map)commonDAO.queryForObject(sql);		
		if(r == null) return "查询不到菜系";	
		
		
		

		Map param = new HashMap();
		param.put("SERIAL_ID", serial_id);
		param.put("NAME", name);
		param.put("DESCRIP", desc);
		param.put("DISPLAY_ORDER", r.get("DISPLAY_ORDER"));
		param.put("PARENT_ID", r.get("PARENT_ID"));
		param.put("SERIAL_LEVEL", r.get("SERIAL_LEVEL"));

		getSqlMapClient().update("courseserial_sqlmap.update_editCourseSerial", param);
		return "修改成功";
			
	
	}
	
	@SuppressWarnings("unchecked")
	public String editCourseSerial2(Map map) throws Exception {

		String serial_id = map.get("SERIAL_ID").toString();
		String name = map.get("NAME").toString();		
		String desc = map.get("DESCRIP").toString();
		String parent_id = map.get("PARENT_ID").toString();
		
		String sql = String.format("select serial_id,name,descrip,display_order,parent_id,serial_level from course_serial where serial_id = %s", serial_id);
		Map r = (Map)commonDAO.queryForObject(sql);		
		if(r == null) return "查询不到菜系";	
		
		
		

		Map param = new HashMap();
		param.put("SERIAL_ID", serial_id);
		param.put("NAME", name);
		param.put("DESCRIP", desc);
		param.put("DISPLAY_ORDER", r.get("DISPLAY_ORDER"));
		param.put("PARENT_ID", parent_id);
		param.put("SERIAL_LEVEL", r.get("SERIAL_LEVEL"));

		getSqlMapClient().update("courseserial_sqlmap.update_editCourseSerial", param);
		return "修改成功";
			
	
	}
	
	
	@SuppressWarnings("unchecked")
	public String delCourseSerial(Map map) throws Exception {

		String serial_id = map.get("SERIAL_ID").toString();

	
		Map param = new HashMap();
		param.put("SERIAL_ID", serial_id);
		param.put("PARENT_ID", serial_id);
		getSqlMapClient().delete("courseserial_sqlmap.delete_CourseSerial", param);
		return "删除成功";
			
	
	}
	
	@SuppressWarnings("unchecked")
	public String delCourseSerial2(Map map) throws Exception {

		String serial_id = map.get("SERIAL_ID").toString();

	
		Map param = new HashMap();
		param.put("SERIAL_ID", serial_id);
		getSqlMapClient().delete("courseserial_sqlmap.delete_CourseSerial2", param);
		return "删除成功";
			
	
	}
	
	/**
	 * 正常流程下订单的下一个状态
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public String nextStatus(Map map) throws Exception {
		/**
		 * 1. 可以查询到订单
		 * 2. 订单状态不能为：
			 	81	客户取消完成
			 	82 	商家取消完成
			 	83	订单确认失败，已取消
			 	99	确认完成
			 	(与数据库的配置相对应)
		 * 3. version未变
		 */
		
		/***注意：与cancelTicket、editTicket的逻辑很相似，以后如果更改，要考虑cancelTicket和editTicket是否也要改 **/
		/******** 例如何时清空锁定者     **/
		
		String ticket_id = map.get("TICKET_ID").toString();
		String myversion = map.get("MYVERSION").toString();		
		String operator = map.get("OPERATOR").toString();		
		
		String sql = String.format("select cust_tel, status, lock_manager, version from ticket where ticket_id = %s", ticket_id);
		Map r = (Map)commonDAO.queryForObject(sql);		
		if(r == null) return "查询不到订单";	
		
		String cust_tel = r.get("CUST_TEL").toString(); //作为订单的文本标识
		
		long cur_status = Long.valueOf(r.get("STATUS").toString()); //订单当前状态
		if(81 == cur_status) {
			return cust_tel + "订单已被客户取消，不能继续流程";
		} else if(82 == cur_status) {
			return cust_tel + "订单已被商家取消，不能继续流程";
		} else if(83 == cur_status) {
			return cust_tel + "订单由于确认失败已被取消，不能继续流程";
		} else if(99 == cur_status) {
			return cust_tel + "订单已确认完成，不能继续流程";
		} else {
			// do nothing
		}
		
		String ts = r.get("VERSION").toString();
		if(!myversion.equals(ts)) return cust_tel+"订单发生了更改，请先刷新订单信息";
		
		Object obj = getSqlMapClient().queryForObject("ticket_sqlmap.query_nextStatus", String.valueOf(cur_status));
		if(obj == null || ((Map)obj).get("NEXT_STATUS")==null) return "找不到下一状态的配置，当前状态为:" + cur_status;
		
		String next_status = ((Map)obj).get("NEXT_STATUS").toString();
		Map param = new HashMap();
		param.put("TICKET_ID", ticket_id);
		param.put("STATUS", next_status);
		param.put("OPERATOR", operator);
		
		//当商家确认时，需要以下信息
		param.put("BUSINESS_RESPONSE", map.get("BUSINESS_RESPONSE"));
		param.put("DISCOUNT_DESCRIP", map.get("DISCOUNT_DESCRIP"));
		param.put("COMMENT_TEXT", map.get("COMMENT_TEXT"));
		param.put("CONTACT", map.get("CONTACT"));
		param.put("NEED_DEPOSIT", map.get("NEED_DEPOSIT"));
		
		param.put("__SET_LOCKMANAGER_NULL", map.get("__SET_LOCKMANAGER_NULL")); //若前台传了__SET_LOCKMANAGER_NULL的值， 则清空锁定者
		
		getSqlMapClient().update("ticket_sqlmap.update_Status", param);
		
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public String confirmfailedTicket(Map map) throws Exception {
		/**
		 * 1. 可以查询到订单
		 * 2. 订单状态不能为：
				31	客户取消,待通知商家	
				41	商家取消,待通知客户
			 	81	客户取消完成
			 	82 	商家取消完成
			 	51	商家确认失败，待通知客户
			 	52	客户确认失败，待通知商家
			 	83	订单确认失败，已取消
		 * 3. version未变
		 */
		
		/***注意：与editTicket、nextStatus 的逻辑很相似，以后如果更改，要考虑editTicket和nextStatus是否也要改 **/
		/******** 例如何时清空锁定者     **/
		
		String ticket_id = map.get("TICKET_ID").toString();
		String myversion = map.get("MYVERSION").toString();		
		String operator = map.get("OPERATOR").toString();
		String from = map.get("FAILED_FROM").toString(); //发起者 1客户 2商家
		
		String sql = String.format("select cust_tel, status, lock_manager, version from ticket where ticket_id = %s", ticket_id);
		Map r = (Map)commonDAO.queryForObject(sql);		
		if(r == null) return "查询不到订单";	
		
		String cust_tel = r.get("CUST_TEL").toString(); //作为订单的文本标识
		
		long cur_status = Long.valueOf(r.get("STATUS").toString()); //订单当前状态
		if(31 == cur_status || 81 == cur_status) {
			return cust_tel + "订单已被客户取消";
		} else if(41 == cur_status || 82 == cur_status) {
			return cust_tel + "订单已被商家取消";
		} else if(51 == cur_status || 52 == cur_status || 83 == cur_status) {
			return cust_tel + "订单的状态已经为确认失败";
		} else {
			//do nothing
		}		
		
		String ts = r.get("VERSION").toString();
		if(!myversion.equals(ts)) return cust_tel+"订单发生了更改";
		
		String new_status;		
		if(from.equals(ConstDefine.s_fromCustom)) { //客户确认失败
			new_status = "52";
		} else if(from.equals(ConstDefine.s_fromBusiness)) { //商家确认失败
			new_status = "51";
		} else {
			return "未知的取消操作发起方";
		}
		
		Map param = new HashMap();
		param.put("TICKET_ID", ticket_id);
		param.put("STATUS", new_status);
		param.put("OPERATOR", operator);
		param.put("__SET_LOCKMANAGER_NULL", map.get("__SET_LOCKMANAGER_NULL")); //若前台传了__SET_LOCKMANAGER_NULL的值， 则清空锁定者
		
		getSqlMapClient().update("ticket_sqlmap.update_Status", param);
		return null;
	}
	/**
	 * 内部使用
	 * @param list
	 * @return
	 */
	@SuppressWarnings("unchecked")	
	private List addition(List list) {		
		if(list == null) return null;
		
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
		for(int n = 0; n < list.size(); ++n) {
			Map map = (Map)list.get(n);
			
			//map.put("DEMAND_TIME_STR", format.format(map.get("DEMAND_TIME")));
			
			//map.put("CREATE_TIME_STR", SZUtility.toString(map.get("CREATE_TIME")));			
			//map.put("LOCK_TIME_STR", SZUtility.toString(map.get("LOCK_TIME")));			
			//map.put("VERSION_STR", SZUtility.toString(map.get("VERSION")));			
		}
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List queryBusinessTickets(Map map) throws Exception {
		List list = getSqlMapClient().queryForList("ticket_sqlmap.query_BusinessTickets", map);
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public long queryBusinessTicketsCount(Map map) throws Exception {
		Map r = (Map)getSqlMapClient().queryForObject("ticket_sqlmap.query_BusinessTicketsCount", map);
		return Long.parseLong(r.get("COUNT").toString());
	}
	
	@SuppressWarnings("unchecked")
	public List queryBusinessTicketsPage(Map map) throws Exception {
		List list = getSqlMapClient().queryForList("ticket_sqlmap.query_BusinessTicketsPage", map);
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public void checkTicket_Business(Map map) throws Exception {
		getSqlMapClient().update("ticket_sqlmap.update_BusinessCheck", map);
	}
	
	@SuppressWarnings("unchecked")
	public void checkTicket_Custom(Map map) throws Exception {
		getSqlMapClient().update("ticket_sqlmap.update_CustomCheck", map);
	}
}
